home *** CD-ROM | disk | FTP | other *** search
/ Over 1,000 Windows 95 Programs / Over 1000 Windows 95 Programs (Microforum) (Disc 2).iso / 1133 / datamat.c < prev    next >
C/C++ Source or Header  |  1997-04-16  |  15KB  |  610 lines

  1. /*
  2. **
  3. **  File:           DATAMAT.C
  4. **  Description:    Contains the data structure and routines used by NEURAL.C
  5. **  Platform:       Windows
  6. **
  7. **
  8. */
  9.  
  10. #include <windows.h>
  11. #include <stdlib.h>
  12. #include <stdio.h>
  13. #include <time.h>
  14. #include <string.h>
  15. #include <ctype.h>
  16. #include <math.h>
  17. #include "nndefs.h"
  18. #include "datamat.h"
  19.  
  20. #define ARRAYCHUNK 100
  21.  
  22.     extern union {
  23.         float f;
  24.         long l;
  25.         } MissingUnion;
  26. #define MISSING (MissingUnion.f)
  27.     void Logit(const char* fmt, ...);
  28.  
  29.     void dump (const char *buf, int count);
  30.     int fgetstr (FILE *fd, LPSTR str);
  31.     int fgetint(FILE *fd);
  32.     long fgetlong(FILE *fd);
  33.     float fgetfloat(FILE *fd);
  34.     void ToUpper (char *s);
  35.     int ChkClip (float f, float hi, float lo);
  36.     
  37. /*
  38. ** ZeroAll
  39. **
  40. ** This function is called to initialize to a known state the internal members of the
  41. ** DATAMAT structure.
  42. ** 
  43. **
  44. ** Arguments:
  45. **
  46. **      DATAMAT *pD        A pointer to the DATAMAT structure to be zapped
  47. **
  48. ** Returns:
  49. **
  50. **      None
  51. */
  52.  
  53. void ZeroAll(DATAMAT *pD) {
  54.  
  55. #ifdef VERBOSE
  56.     Logit ("Zeroall\n");
  57. #endif
  58.     pD->m_version = REVLEVEL;
  59.     pD->m_numtests = 0 ;
  60.     pD->m_numcols = 0 ;
  61.     pD->m_numrows = 0 ;
  62.     pD->m_ninputs = 0 ;
  63.     pD->m_maxrows = 0;
  64.     pD->m_maxtests = 0 ;
  65.     pD->m_noutputs = 0 ;
  66.     pD->m_maxrows = pD->m_rawcols = pD->m_rawrows = 0;
  67.     pD->m_istate = NFobject_exists;
  68.  
  69.     pD->m_icrossref = NULL;
  70.     pD->m_ocrossref = NULL;
  71.     pD->m_coldesc = NULL;
  72.     pD->m_rowdesc = NULL;
  73.     pD->m_icoldesc = NULL;
  74.     pD->m_ocoldesc = NULL;
  75.     pD->m_iarray = NULL;
  76.     pD->m_oarray = NULL;
  77.     pD->m_itarray = NULL;
  78.     pD->m_otarray = NULL;
  79.     pD->m_title[0] = pD->m_desc[0] = pD->m_parfname[0] = pD->m_rawfname[0] = 0;
  80. }              
  81.  
  82. /*
  83. ** DCreateDataMat
  84. **
  85. ** This function is called to create a new DATAMAT structure
  86. ** 
  87. **
  88. ** Arguments:
  89. **
  90. **      None
  91. **
  92. ** Returns:
  93. **
  94. **      DATAMAT *        Returns a pointer to the created DATAMAT structure
  95. */
  96.  
  97. DATAMAT *DCreateDataMat()
  98. {             
  99.     DATAMAT *pD;
  100.     pD = (DATAMAT*) malloc (sizeof(DATAMAT));
  101.     
  102. #ifdef VERBOSE
  103.     Logit ("CDataMat null constructor\n");
  104. #endif
  105.     ZeroAll(pD);        
  106.     return pD;
  107. }
  108.  
  109. /*
  110. ** ZeroColDesc
  111. **
  112. ** This function is called to initialize the column descriptors to a known state
  113. ** 
  114. **
  115. ** Arguments:
  116. **
  117. **      DATAMAT *pD        A pointer to the DATAMAT structure
  118. **      int num            The number of columns to initialize
  119. **      COL_DESC* desc    A pointer to the column descriptor
  120. **
  121. ** Returns:
  122. **
  123. **      None
  124. */
  125.  
  126. void ZeroColDesc(DATAMAT *pD, int num,COL_DESC* desc)
  127. {
  128.     int i;
  129.     for (i=0;i<num;i++) {
  130.         desc[i].fscale =
  131.         desc[i].foffset = 0.0f;
  132.         desc[i].max = 0.0f;
  133.         desc[i].min = 0.0f;
  134.         desc[i].fieldtype=0;
  135.         desc[i].cliphi = MISSING;
  136.         desc[i].cliplo = MISSING;
  137.         desc[i].colwidth = 90;
  138.         desc[i].flag = 0;
  139.         desc[i].col_usage = 'N';
  140.         strcpy (&desc[i].format[0],"%s");
  141.         desc[i].vlab[0]=0;
  142.         desc[i].units[0]=0;
  143.         if (pD->m_icrossref!=NULL) pD->m_icrossref[i] = pD->m_ocrossref[i] = -1;
  144.     }
  145. }
  146.  
  147. /*
  148. ** DDeleteDataMat
  149. **
  150. ** This function is called to destroy a DATAMAT structure
  151. ** 
  152. **
  153. ** Arguments:
  154. **
  155. **      DATAMAT *pD        A pointer to the DATAMAT structure
  156. **
  157. ** Returns:
  158. **
  159. **      None
  160. */
  161.  
  162. void DDeleteDataMat(DATAMAT *pD)
  163. {
  164.  
  165. #ifdef VERBOSE
  166.     Logit ("CDataMat DeleteContents istate=%lx\n",pD->m_istate);
  167. #endif
  168.     if (pD->m_istate & NFnum_col_known) {
  169.         free  (pD->m_coldesc);
  170.         free (pD->m_icrossref);
  171.         free (pD->m_ocrossref);
  172.     }
  173.  
  174.     free (pD->m_icoldesc);
  175.     free (pD->m_ocoldesc);
  176.     
  177. #ifdef VERBOSE
  178.     Logit ("CDataMat Delete Arrays\n");
  179. #endif
  180.     if (pD->m_istate&NFtrainmat_loaded) {
  181.         if (pD->m_ninputs) 
  182.             free_2d_floats (pD->m_iarray,pD->m_ninputs);
  183.         if (pD->m_noutputs) 
  184.             free_2d_floats (pD->m_oarray,pD->m_noutputs);
  185.     }
  186.     if (pD->m_istate&NFtestmat_loaded) {
  187.         if (pD->m_ninputs) 
  188.             free_2d_floats (pD->m_itarray,pD->m_ninputs);
  189.         if (pD->m_noutputs) 
  190.             free_2d_floats (pD->m_otarray,pD->m_noutputs);
  191.     }
  192.  
  193.     free (pD);
  194. }
  195.  
  196. /*
  197. ** DSetInputVal
  198. **
  199. ** This function is called to set a cell in the training input matrix
  200. ** 
  201. **
  202. ** Arguments:
  203. **
  204. **      DATAMAT *pD        A pointer to the DATAMAT structure
  205. **      int row            The row number of the cell
  206. **      int col            The column number of the cell
  207. **      float val        The value to set the cell
  208. **                                                              
  209. ** Returns:
  210. **
  211. **      None
  212. */
  213.  
  214. void DSetInputVal(DATAMAT *pD, int row, int col, float val ) {
  215.     pD->m_iarray[col][row] = val;
  216. }
  217.  
  218. /*
  219. ** DSetInputTVal
  220. **
  221. ** This function is called to set a cell in the test input matrix
  222. ** 
  223. **
  224. ** Arguments:
  225. **
  226. **      DATAMAT *pD        A pointer to the DATAMAT structure
  227. **      int row            The row number of the cell
  228. **      int col            The column number of the cell
  229. **      float val        The value to set the cell
  230. **                                                              
  231. ** Returns:
  232. **
  233. **      None
  234. */
  235.  
  236. void DSetInputTVal(DATAMAT *pD, int row, int col, float val ) {
  237.     pD->m_itarray[col][row] = val;
  238. }
  239.  
  240. /*
  241. ** DSetOutputVal
  242. **
  243. ** This function is called to set a cell in the training output matrix
  244. ** 
  245. **
  246. ** Arguments:
  247. **
  248. **      DATAMAT *pD        A pointer to the DATAMAT structure
  249. **      int row            The row number of the cell
  250. **      int col            The column number of the cell
  251. **      float val        The value to set the cell
  252. **                                                              
  253. ** Returns:
  254. **
  255. **      None
  256. */
  257.  
  258. void DSetOutputVal(DATAMAT *pD, int row, int col, float val ) {
  259.     pD->m_oarray[col][row] = val;
  260. }
  261.  
  262. /*
  263. ** DSetOutputTVal
  264. **
  265. ** This function is called to set a cell in the test output matrix
  266. ** 
  267. **
  268. ** Arguments:
  269. **
  270. **      DATAMAT *pD        A pointer to the DATAMAT structure
  271. **      int row            The row number of the cell
  272. **      int col            The column number of the cell
  273. **      float val        The value to set the cell
  274. **                                                              
  275. ** Returns:
  276. **
  277. **      None
  278. */
  279.  
  280. void DSetOutputTVal(DATAMAT *pD, int row, int col, float val ) {
  281.     pD->m_otarray[col][row] = val;
  282. }
  283.  
  284. /*
  285. ** DRescale
  286. **
  287. ** This function is called to re-scale the passed value back to user units
  288. ** 
  289. **
  290. ** Arguments:
  291. **
  292. **      DATAMAT *pD        A pointer to the DATAMAT structure
  293. **      float f            The value to re-scale
  294. **      char C            Contains a 'I' for input and 'O' for output
  295. **      int ix            The index to the column descriptor
  296. **                                                              
  297. ** Returns:
  298. **
  299. **      float            Returns the re-scaled value
  300. */
  301.  
  302. float DRescale(DATAMAT *pD, float f,char C,int ix) {
  303.     if (f==MISSING) return f;
  304.     if (C=='I') {
  305.         f /= pD->m_icoldesc[ix].fscale;
  306.         f -= pD->m_icoldesc[ix].foffset;
  307.     }
  308.     if (C=='O') {
  309.         f /= pD->m_ocoldesc[ix].fscale;
  310.         f -= pD->m_ocoldesc[ix].foffset;
  311.     }             
  312.     return f;
  313. }
  314.  
  315. /*
  316. ** DScale
  317. **
  318. ** This function is called to scale the passed value from user units to neural units
  319. ** 
  320. **
  321. ** Arguments:
  322. **
  323. **      DATAMAT *pD        A pointer to the DATAMAT structure
  324. **      float f            The value to scale
  325. **      char C            Contains a 'I' for input and 'O' for output
  326. **      int ix            The index to the column descriptor
  327. **                                                              
  328. ** Returns:
  329. **
  330. **      float            Returns the scaled value
  331. */
  332.  
  333. float DScale(DATAMAT *pD, float f,char C,int ix) {
  334.     if (C=='I') {
  335.         f += pD->m_icoldesc[ix].foffset;
  336.         f *= pD->m_icoldesc[ix].fscale;
  337.     }
  338.     if (C=='O') {
  339.         f += pD->m_ocoldesc[ix].foffset;
  340.         f *= pD->m_ocoldesc[ix].fscale;
  341.     }
  342.     return f;
  343. }
  344.  
  345. /*
  346. ** DRescaleFmt
  347. **
  348. ** This function is called to re-scale the passed value from neural units to users units.
  349. ** The function also builds a formatted string. The format is determined by the format
  350. ** string stored in the column descriptor
  351. ** 
  352. **
  353. ** Arguments:
  354. **
  355. **      DATAMAT *pD        A pointer to the DATAMAT structure
  356. **      float f            The value to scale
  357. **      char C            Contains a 'I' for input and 'O' for output
  358. **      int ix            The index to the column descriptor
  359. **                                                              
  360. ** Returns:
  361. **
  362. **      char *            Returns a pointer to the formatted string
  363. */
  364.  
  365. char * DRescaleFmt(DATAMAT *pD,float f,char C,int ix) {
  366.     float val;     
  367.     static char buf[40];
  368.     
  369.     if (f==MISSING) return " . ";
  370.     val = DRescale(pD,f,C,ix);
  371.     if (C=='O') {
  372.         sprintf (buf,&pD->m_ocoldesc[ix].format[0],val);
  373.         strncpy (&pD->m_ocoldesc[ix].convstr[0],buf,20);
  374.         pD->m_ocoldesc[ix].convstr[19]=0;
  375.         return &pD->m_ocoldesc[ix].convstr[0];
  376.     }
  377.     if (C=='I') {
  378.         sprintf (buf,&pD->m_icoldesc[ix].format[0],val);
  379.         strncpy (&pD->m_icoldesc[ix].convstr[0],buf,20);
  380.         pD->m_icoldesc[ix].convstr[19]=0;
  381.         return &pD->m_icoldesc[ix].convstr[0];
  382.     }
  383.     return "BadC";
  384. }
  385.  
  386. /*
  387. ** dtransl
  388. **
  389. ** This function is used internally by the import data matrix function.
  390. ** 
  391. **
  392. ** Arguments:
  393. **
  394. **      char *cdummy          A pointer to a character string
  395. **
  396. ** Returns:
  397. **
  398. **      int        returns the tranlated string or a -1 if the string doesn't start with 'D'
  399. */
  400.  
  401. int dtransl(char *cdummy)
  402. {
  403.     int val=0;
  404.     if (cdummy[0] == 'D') {
  405.         val = atoi(&cdummy[1]);
  406.         if (val > 8) return -1;
  407.         return val;
  408.     }
  409.     if (cdummy[0] == 'M') return 0;
  410.     if (cdummy[0] == 'T') return 1000;
  411.     return -1;
  412. }
  413.  
  414. /*
  415. ** DImportDataMat
  416. **
  417. ** This function is called to import a data matrix from an ENN file.
  418. ** 
  419. **
  420. ** Arguments:
  421. **
  422. **      DATAMAT *pD     A pointer to the datamat structure to load
  423. **      FILE *fd        A pointer to the open ENN file
  424. **
  425. ** Returns:
  426. **
  427. **      int        returns a zero is the datamat is imported without error
  428. */
  429.  
  430. int DImportDataMat(DATAMAT *pD, FILE *fd) {
  431.     int i,numtrain,numtest;
  432.     static char cdummy[128];
  433.     int sel,stat,lastsel;
  434.     float f;                   
  435.     time_t ttime;
  436.     sel=0;
  437.                       
  438. #ifdef VERBOSE
  439.     Logit("Start import DM\n");
  440. #endif
  441.     numtrain = numtest = 0;
  442. top:
  443.     stat= fgetstr(fd,cdummy);
  444.     if (stat==EOF) {
  445. #ifdef VERBOSE
  446.         Logit("Finished import DM\n");
  447. #endif
  448.         return 0;
  449.     }
  450.     lastsel = sel;
  451.     sel = dtransl(cdummy);
  452.     switch (sel) {
  453.     default: //error
  454.         goto errorexit;
  455.         break;
  456.     case 0: //training data
  457.         for(i=0;i<pD->m_ninputs;i++) {
  458.             f=fgetfloat(fd);
  459.             DSetInputVal(pD,numtrain,i,DScale(pD,f,'I',i));
  460.         }
  461.         for(i=0;i<pD->m_noutputs;i++) {
  462.             f=fgetfloat(fd);
  463.             DSetOutputVal(pD,numtrain,i,DScale(pD,f,'O',i));
  464.         }                        
  465.         numtrain++;
  466.         break;
  467.     case 1000: // test data
  468.         for(i=0;i<pD->m_ninputs;i++) {
  469.             f=fgetfloat(fd);
  470.             DSetInputTVal(pD,numtest,i,DScale(pD,f,'I',i));
  471.         }
  472.         for(i=0;i<pD->m_noutputs;i++) {
  473.             f=fgetfloat(fd);
  474.             DSetOutputTVal(pD,numtest,i,DScale(pD,f,'O',i));
  475.         }                        
  476.         numtest++;
  477.         break;
  478.     case 1:
  479.         pD->m_istate = fgetlong(fd);
  480.         pD->m_numcols = fgetint(fd);
  481.         pD->m_numrows = fgetint(fd);
  482.         pD->m_ninputs = fgetint(fd);
  483.         pD->m_noutputs = fgetint(fd);
  484.         pD->m_rawrows = fgetint(fd);
  485.         pD->m_rawcols = fgetint(fd);
  486.         pD->m_total = fgetint(fd);
  487.  
  488.  
  489.         if (pD->m_istate&NFnum_col_known) {
  490.             pD->m_coldesc = (COL_DESC*) malloc (sizeof(COL_DESC)*pD->m_numcols);
  491.             pD->m_icrossref = (int*) malloc (sizeof(int)*pD->m_numcols);
  492.             pD->m_ocrossref = (int*) malloc (sizeof(int)*pD->m_numcols);
  493.             for (i=0;i<pD->m_numcols;i++) {
  494.                 pD->m_icrossref[i]=0;
  495.                 pD->m_ocrossref[i]=0;
  496.             }
  497.             for (i=0;i<pD->m_numcols;i++) {
  498.                 pD->m_coldesc[i].fscale = 0.f;
  499.                 pD->m_coldesc[i].foffset = 0.f; 
  500.                 pD->m_coldesc[i].cliphi = pD->m_coldesc[i].cliplo = MISSING;
  501.                 pD->m_coldesc[i].max = 0.f;
  502.                 pD->m_coldesc[i].min = 0.f;
  503.                 pD->m_coldesc[i].flag = 0;
  504.                 pD->m_coldesc[i].fieldtype = 0;
  505.                 pD->m_coldesc[i].col_usage = 'U';
  506.                 pD->m_coldesc[i].format[0] = 0;
  507.                 pD->m_coldesc[i].vlab[0] = 0;
  508.                 pD->m_coldesc[i].units[0] = 0;
  509.                 pD->m_coldesc[i].colwidth = 90;
  510.             }
  511.  
  512.         }
  513.         pD->m_istate = NFobject_exists | NFnum_col_known | 
  514.                     NFtrainmat_loaded | NFi_o_col_known;
  515.         if (pD->m_istate&NFtrainmat_loaded) {
  516.             pD->m_icoldesc = (COL_DESC*) malloc (sizeof(COL_DESC)*pD->m_ninputs);
  517.             pD->m_ocoldesc = (COL_DESC*) malloc (sizeof(COL_DESC)*pD->m_noutputs);
  518.             if (pD->m_numrows) {
  519.                 pD->m_iarray = alloc_2d_floats (pD->m_ninputs,pD->m_numrows);
  520.                 pD->m_oarray = alloc_2d_floats (pD->m_noutputs,pD->m_numrows);
  521.             } else pD->m_istate &= ~NFtrainmat_loaded;
  522.         }
  523.         break;
  524.     case 2:      
  525.         fgetstr(fd,cdummy);
  526.         strncpy (pD->m_title,cdummy,MAXCSTRING);
  527.         fgetstr(fd,cdummy);
  528.         strncpy (pD->m_desc,cdummy,MAXCSTRING);
  529.         fgetstr(fd,cdummy);
  530.         strncpy (pD->m_rawfname,cdummy,MAXCSTRING);
  531.         fgetstr(fd,cdummy);
  532.         strncpy (pD->m_parfname,cdummy,MAXCSTRING);
  533.         ttime = fgetlong(fd);
  534.  
  535.         pD->m_istate |= (NFtitle_known    | NFdesc_known |
  536.                      NFraw_file_known );
  537.         break;
  538.     case 3:
  539.         i=fgetint(fd);
  540.         pD->m_coldesc[i].flag = fgetint(fd);
  541.         pD->m_coldesc[i].fieldtype = fgetint(fd);
  542.         pD->m_coldesc[i].fscale = fgetfloat(fd);
  543.         pD->m_coldesc[i].foffset = fgetfloat(fd);
  544.         pD->m_coldesc[i].max = fgetfloat(fd);
  545.         pD->m_coldesc[i].min = fgetfloat(fd);
  546.         fgetstr(fd,cdummy);
  547.         pD->m_coldesc[i].col_usage=cdummy[0];
  548.         fgetstr(fd,pD->m_coldesc[i].format);
  549.         fgetstr(fd,pD->m_coldesc[i].vlab);
  550.  
  551.         pD->m_coldesc[i].units[0] = 0;
  552.         pD->m_coldesc[i].cliphi = pD->m_coldesc[i].cliplo = MISSING;
  553.         pD->m_coldesc[i].colwidth = 90;
  554.         pD->m_istate |= NFcol_usage_known;
  555.         break;
  556.     case 4:
  557.         for (i=0;i<pD->m_numcols;i++) pD->m_icrossref[i]=fgetint(fd);
  558.         break;
  559.     case 5:
  560.         for (i=0;i<pD->m_numcols;i++) pD->m_ocrossref[i]=fgetint(fd);
  561.         break;
  562.     case 6:
  563.         i=fgetint(fd);
  564.         pD->m_icoldesc[i].flag = fgetint(fd);
  565.         pD->m_icoldesc[i].fieldtype = fgetint(fd);
  566.         pD->m_icoldesc[i].fscale = fgetfloat(fd);
  567.         pD->m_icoldesc[i].foffset = fgetfloat(fd);
  568.         pD->m_icoldesc[i].max = fgetfloat(fd);
  569.         pD->m_icoldesc[i].min = fgetfloat(fd);
  570.         fgetstr(fd,cdummy);
  571.         pD->m_icoldesc[i].col_usage=cdummy[0];
  572.         fgetstr(fd,pD->m_icoldesc[i].format);
  573.         fgetstr(fd,pD->m_icoldesc[i].vlab);
  574.         pD->m_icoldesc[i].units[0] = 0;
  575.         pD->m_icoldesc[i].colwidth = 90;
  576.         pD->m_icoldesc[i].cliphi = pD->m_icoldesc[i].cliplo = MISSING;
  577.         pD->m_istate |= NFcol_usage_known | NFi_o_col_known;
  578.         break;
  579.     case 7:
  580.         i=fgetint(fd);
  581.         pD->m_ocoldesc[i].flag = fgetint(fd);
  582.         pD->m_ocoldesc[i].fieldtype = fgetint(fd);
  583.         pD->m_ocoldesc[i].fscale = fgetfloat(fd);
  584.         pD->m_ocoldesc[i].foffset = fgetfloat(fd);
  585.         pD->m_ocoldesc[i].max = fgetfloat(fd);
  586.         pD->m_ocoldesc[i].min = fgetfloat(fd);
  587.         fgetstr(fd,cdummy);
  588.         pD->m_ocoldesc[i].col_usage=cdummy[0];
  589.         fgetstr(fd,pD->m_ocoldesc[i].format);
  590.         fgetstr(fd,pD->m_ocoldesc[i].vlab);
  591.         pD->m_ocoldesc[i].units[0] = 0;
  592.         pD->m_ocoldesc[i].colwidth = 90;
  593.         pD->m_ocoldesc[i].cliphi = pD->m_ocoldesc[i].cliplo = MISSING;
  594.         pD->m_istate |= NFcol_usage_known | NFi_o_col_known;
  595.         break;
  596.     case 8: //NUMBER OF TEST ROWS
  597.         pD->m_numtests = fgetint(fd);
  598.         if (pD->m_numtests) {
  599.             pD->m_itarray = alloc_2d_floats (pD->m_ninputs,pD->m_numtests);
  600.             pD->m_otarray = alloc_2d_floats (pD->m_noutputs,pD->m_numtests);
  601.             pD->m_istate |= NFtestmat_loaded;                     
  602.         }
  603.         break;
  604.     }                          
  605.     goto top;
  606.  
  607. errorexit:
  608.     return -1;
  609. }
  610.